From: Keir Fraser Date: Tue, 28 Oct 2008 11:25:20 +0000 (+0000) Subject: x86: Fix circular page reference destruction in relinquish_memory(). X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14054^2~18 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=889f104e6a27716d8e7fcfa72cc516a6b207ce87;p=xen.git x86: Fix circular page reference destruction in relinquish_memory(). Tested by Jan Beulich and fixes a memory leak, but there is more to be done here. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 30f03c99ac..0c39db4718 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1687,7 +1687,6 @@ static int relinquish_memory( { if ( free_page_type(page, x, 0) != 0 ) BUG(); - put_page(page); break; } } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index b2a9c3a085..fdd70d2dd9 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1973,6 +1973,7 @@ int free_page_type(struct page_info *page, unsigned long type, page->nr_validated_ptes = 1U << PAGETABLE_ORDER; page->partial_pte = 0; } + switch ( type & PGT_type_mask ) { case PGT_l1_page_table: @@ -1998,6 +1999,15 @@ int free_page_type(struct page_info *page, unsigned long type, BUG(); } + return rc; +} + + +static int __put_final_page_type( + struct page_info *page, unsigned long type, int preemptible) +{ + int rc = free_page_type(page, type, preemptible); + /* No need for atomic update of type_info here: noone else updates it. */ if ( rc == 0 ) { @@ -2062,7 +2072,7 @@ static int __put_page_type(struct page_info *page, x, nx)) != x) ) continue; /* We cleared the 'valid bit' so we do the clean up. */ - return free_page_type(page, x, preemptible); + return __put_final_page_type(page, x, preemptible); } /*